# -*- coding: utf-8 -*-
# @file    : command
# @Date    : 2020/11/30
# @Author  :
# @Version : 1.0.0
"""
Simple Command
"""
import os
import sys
import shutil
import zipfile
import time
import requests

from .log import logger as _logger
from ._misc import gen_bak_file_name, get_abs_path, proxy, store_file
from .config import config
from .constant import GIT

user_config = config['user']


class Command(object):
    """
    简单的命令执行和注册
    """
    _cmd = {}

    @classmethod
    def invoke(cls, name):
        if name not in cls._cmd:
            _logger.error("没有命令: %s", name)
            return
        success = cls._cmd[name]()
        if not success:
            sys.exit(0)

    @classmethod
    def cli(cls, name):
        def decorator(func):
            cls._cmd[name] = func
            return func

        return decorator


@Command.cli('clear')
def clear_static_dir():
    _logger.info("即将对静态资源进行清理...")
    time.sleep(.5)
    static_dir = get_abs_path(user_config['static_dir'])
    try:
        shutil.rmtree(static_dir)
        os.makedirs(static_dir)
        _logger.info("清理工作已完成.", )
    except Exception as e:
        _logger.error("清理过程发生错误: %s", e)
        return False

    return True


@Command.cli('backup')
def backup_static_dir():
    """
    对静态资源目录执行备份
    :return:
    """
    _logger.info("即将对静态资源进行备份...")
    time.sleep(.5)
    fn = gen_bak_file_name()
    static_dir = get_abs_path(user_config['static_dir'])

    z = zipfile.ZipFile(fn, 'w', zipfile.ZIP_DEFLATED)
    error = False
    try:
        for dir_path, _, files in os.walk(get_abs_path(user_config['static_dir'])):
            for f in files:
                f_path = os.path.join(dir_path, f)
                _logger.info("处理文件: %s", f_path)
                z.write(f_path, f_path[len(static_dir):])

        _logger.info("备份工作已完成!!!!")
        _logger.info("文件路径, %s", fn)
    except Exception as e:
        _logger.error("备份过程发送错误: %s", e)
        _logger.warn("删除错误的文件: %s", fn)
        error = True
    finally:
        z.close()
        if error:
            os.remove(fn)
            return False

    return True


@Command.cli('restore')
def restore_static_dir_from_git():
    """
    从git地址恢复静态资源, 用于备用更新和修复资源错误
    :return:
    """
    _logger.info("即将从项目GIT地址更新/恢复静态资源文件...")
    time.sleep(.5)
    static_dir = get_abs_path(user_config['static_dir'])
    branch_url = GIT + '/raw/static-latest'
    list_url = branch_url + '/UPDATE.txt'
    _logger.info("拉取资源列表: %s", list_url)
    response = proxy(requests.get, url=list_url)
    if not response or response.status_code != 200:
        _logger.info("获取资源列表失败")
        return False

    text = response.text.replace('\r\n', '\n').replace('\r', '\n')
    lines = text.split('\n')
    res_list = lines[5:]
    _logger.info("获取资源列表成功, 文件总数: %s", len(res_list))
    _logger.info(lines[0])
    _logger.info(lines[1])
    _logger.info(lines[2])
    _logger.info(lines[3])
    # TODO 使用异步多任务
    for index, res in enumerate(res_list, start=1):
        res = res.strip().replace('\\', '/')
        res_url = branch_url + '/' + res
        response = proxy(requests.get, url=res_url)
        if not response or response.status_code != 200:
            _logger.info("下载资源[%s/%s]: \t%s \t%s", index, len(res_list), res, '失败')
            return False
        _logger.info("下载资源[%s/%s]: \t%s \t%s", index, len(res_list), res, '成功')
        store_file(os.path.join(static_dir, res), response.content)
    _logger.info("资源文件更新/恢复成功! 请重启服务并清除浏览器缓存.")
    return True
